#pragma once
#include "InetAddr.hpp"
#include "LockGuard.hpp"
#include "ThreadPool.hpp"
#include <vector>
#include <pthread.h>
#include <functional>
#include <sys/types.h>
#include <sys/socket.h>

using task_t = function<void()>;

class MessageRoute
{
private:
    // 判断是否存在
    bool IsExist(const InetAddr &addr)
    {
        auto it = _online_users.begin();
        while (it != _online_users.end())
        {
            if (*it == addr)
                return true;
            ++it;
        }
        return false;
    }

public:
    MessageRoute()
    {
        // 初始化一下锁
        pthread_mutex_init(&_mutex, nullptr);
    }

    void AddUser(const InetAddr &addr)
    {
        // 访问需要加锁
        LockGuard lockguard(&_mutex);
        if (IsExist(addr))
            return;

        // 不存在加入
        _online_users.push_back(addr);
    }

    void DelUser(const InetAddr &addr)
    {
        // 访问需要加锁
        LockGuard lockguard(&_mutex);

        auto it = _online_users.begin();
        while (it != _online_users.end())
        {
            if (*it == addr)
            {
                _online_users.erase(it);
                break;
            }
            ++it;
        }
    }

    void RouteHelper(int socketfd,std::string message,InetAddr who)
    {
        // 访问需要加锁
        LockGuard lockguard(&_mutex);
        string message_send = "["+who.Ip()+":"+std::to_string(who.Port())+"]#"+message+"\n";
        //把这条信息转发给所有用户
        for(auto u : _online_users)
        { 
            struct sockaddr_in useraddr_in = u.Addr();
            sendto(socketfd,message_send.c_str(),message_send.size(),0,(struct sockaddr*)&useraddr_in,sizeof(useraddr_in));
        }
    }


    void Route(int socketfd,std::string message,InetAddr who)
    {
        //上来默认加入用户
        AddUser(who);
        
        //删除用户逻辑
        if(message =="Q"||message =="QUIT")
        {
            DelUser(who);
        }


        //创建进程进程池，把任务放到任务队列中
        
        task_t task = std::bind(&MessageRoute::RouteHelper,this,socketfd,message,who);
        ThreadPool<task_t>::GetInstance()->EnQueue(task);
    }
    ~MessageRoute()
    {
        pthread_mutex_destroy(&_mutex);
    }

private:
    vector<InetAddr> _online_users; // 存放在线用户的ip和port
    pthread_mutex_t _mutex;
};
